const fs = require('fs').promises;
const fsSync = require('fs');
const path = require('path');
const iconv = require('iconv-lite');
const chardet = require('chardet');

/**
 * 获取文件元数据，包括大小、修改时间和编码
 * @param {string} filePath 文件路径
 * @returns {Promise<Object>} 文件元数据
 */
async function getFileMetadata(filePath) {
  try {
    const stats = await fs.stat(filePath);
    const encoding = await detectEncoding(filePath);
    
    // 格式化文件大小
    const sizeInMB = stats.size / (1024 * 1024);
    const formattedSize = sizeInMB.toFixed(2) + ' MB';
    
    return {
      size: stats.size,
      formattedSize,
      modifiedAt: stats.mtime,
      encoding
    };
  } catch (err) {
    console.error(`[splitter] 获取文件元数据失败: ${filePath}`, err);
    throw err;
  }
}

/**
 * 检测文件编码
 * @param {string} filePath 文件路径
 * @returns {Promise<string>} 检测到的编码
 */
async function detectEncoding(filePath) {
  try {
    console.log(`[splitter] 开始检测文件编码: ${filePath}`);
    
    // 首先尝试读取文件头部进行分析
    const fileHandle = await fs.open(filePath, 'r');
    try {
      // 读取前8KB用于检测
      const buffer = Buffer.alloc(8192);
      const { bytesRead } = await fileHandle.read(buffer, 0, buffer.length, 0);
      
      if (bytesRead === 0) {
        console.warn(`[splitter] 文件为空: ${filePath}`);
        return 'utf8'; // 默认使用utf8
      }
      
      // 截取实际读取的字节
      const content = buffer.slice(0, bytesRead);
      
      // 检查BOM标记
      if (content.length >= 3 && content[0] === 0xEF && content[1] === 0xBB && content[2] === 0xBF) {
        console.log(`[splitter] 检测到UTF-8 BOM标记`);
        return 'utf8';
      }
      
      if (content.length >= 2) {
        // UTF-16 LE
        if (content[0] === 0xFF && content[1] === 0xFE) {
          console.log(`[splitter] 检测到UTF-16 LE BOM标记`);
          return 'utf16le';
        }
        // UTF-16 BE
        if (content[0] === 0xFE && content[1] === 0xFF) {
          console.log(`[splitter] 检测到UTF-16 BE BOM标记`);
          return 'utf16be';
        }
      }
      
      // 使用chardet库进行编码检测
      const result = chardet.detect(content);
      
      if (result) {
        let encoding = result.toLowerCase();
        
        // 转换chardet返回的编码名称为iconv-lite兼容的格式
        if (encoding === 'utf-8') encoding = 'utf8';
        if (encoding === 'gb2312' || encoding === 'gb18030') encoding = 'gbk';
        
        console.log(`[splitter] chardet检测到编码: ${encoding}`);
        return encoding;
      }
      
      // 使用启发式方法进行GBK检测
      // 计算无效UTF-8字符的比例
      let invalidUtf8Count = 0;
      let potentialGbkCount = 0;
      
      for (let i = 0; i < bytesRead; i++) {
        const byte = content[i];
        
        // 检查多字节UTF-8序列的首字节
        if ((byte & 0xE0) === 0xC0) { // 2字节序列的首字节
          if (i + 1 < bytesRead && (content[i + 1] & 0xC0) === 0x80) {
            i += 1; // 跳过有效的后续字节
          } else {
            invalidUtf8Count++;
          }
        } else if ((byte & 0xF0) === 0xE0) { // 3字节序列的首字节
          if (i + 2 < bytesRead && 
              (content[i + 1] & 0xC0) === 0x80 && 
              (content[i + 2] & 0xC0) === 0x80) {
            i += 2; // 跳过有效的后续字节
          } else {
            invalidUtf8Count++;
          }
        } else if ((byte & 0xF8) === 0xF0) { // 4字节序列的首字节
          if (i + 3 < bytesRead && 
              (content[i + 1] & 0xC0) === 0x80 && 
              (content[i + 2] & 0xC0) === 0x80 && 
              (content[i + 3] & 0xC0) === 0x80) {
            i += 3; // 跳过有效的后续字节
          } else {
            invalidUtf8Count++;
          }
        } else if ((byte & 0x80) !== 0) { // 非ASCII字符但不是UTF-8多字节序列的首字节
          invalidUtf8Count++;
          
          // 检查是否可能是GBK双字节字符
          if (i + 1 < bytesRead && 
              byte >= 0x81 && byte <= 0xFE && 
              content[i + 1] >= 0x40 && content[i + 1] <= 0xFE) {
            potentialGbkCount++;
          }
        }
      }
      
      const invalidRatio = invalidUtf8Count / bytesRead;
      console.log(`[splitter] UTF-8无效字符比例: ${(invalidRatio * 100).toFixed(2)}%, 潜在GBK字符数: ${potentialGbkCount}`);
      
      // 如果无效UTF-8字符比例较高且存在潜在GBK字符，尝试读取为GBK
      if (invalidRatio > 0.1 && potentialGbkCount > 10) {
        console.log(`[splitter] 基于启发式分析，判断为GBK编码`);
        return 'gbk';
      }
      
      console.log(`[splitter] 未能明确检测到编码，默认使用UTF-8`);
      return 'utf8';
      
    } finally {
      await fileHandle.close();
    }
    
  } catch (err) {
    console.error(`[splitter] 检测文件编码失败: ${filePath}`, err);
    // 默认返回UTF-8
    return 'utf8';
  }
}

/**
 * 读取文件内容（使用正确的编码）
 * @param {string} filePath 文件路径
 * @param {string} encoding 文件编码
 * @returns {Promise<string>} 文件内容
 */
async function readFileContent(filePath, encoding = 'utf8') {
  try {
    console.log(`[splitter] 开始读取文件: ${filePath}, 编码: ${encoding}`);
    
    // 读取文件的二进制数据
    const buffer = await fs.readFile(filePath);
    console.log(`[splitter] 文件读取完成，大小: ${buffer.length} 字节`);
    
    // 使用指定编码解码文件内容
    let content = '';
    
    // 处理特殊情况：UTF-16
    if (encoding === 'utf16le' || encoding === 'utf16be') {
      // 检查BOM
      let skipBOM = false;
      if (buffer.length >= 2) {
        if (encoding === 'utf16le' && buffer[0] === 0xFF && buffer[1] === 0xFE) {
          skipBOM = true;
        } else if (encoding === 'utf16be' && buffer[0] === 0xFE && buffer[1] === 0xFF) {
          skipBOM = true;
        }
      }
      
      // 解码，跳过BOM（如果有）
      const startPos = skipBOM ? 2 : 0;
      content = iconv.decode(buffer.slice(startPos), encoding);
    } 
    // 处理UTF-8 BOM
    else if (encoding === 'utf8' && buffer.length >= 3 && 
             buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
      content = iconv.decode(buffer.slice(3), encoding);
    }
    // 标准解码
    else {
      content = iconv.decode(buffer, encoding);
    }
    
    console.log(`[splitter] 文件内容解码完成，字符数: ${content.length}`);
    return content;
  } catch (err) {
    console.error(`[splitter] 读取文件内容失败: ${filePath}`, err);
    throw err;
  }
}

module.exports = {
  getFileMetadata,
  detectEncoding,
  readFileContent
};